#ifndef OBJETOMOVIBLE_H_
#define OBJETOMOVIBLE_H_
#include <string>
#include <vector>
#include <iostream>
#include <typeinfo>

#include "ObjetoEstatico.h"
#include "Obstaculos/Obstaculo.h"

#define GRAVEDAD_DEFAULT 300

using namespace std;

class EstadoBasico {
	public:
		static const int Movimiento;
		static const int Saltando;
		static const int Quieto;
		static const int Animando;
		static const vector<int> acciones;
		static const vector<int> animaciones;
};

template <typename Tipo>
class make_vector {
	
	private:
		std::vector<Tipo> data_;
		
	public:
		make_vector<Tipo>& operator<< (const Tipo& valor) {
			data_.push_back(valor);
			return *this;
		}
		
		operator std::vector<Tipo>() const {
			return data_;
		}
};

enum EstadoMovimiento {
	Empezo, // se corresponde con Presiono de InputCliente
	Freno, // se corresponde con Libero de InputCliente
	Moviendo,
	SinMovimiento,
};

class ObjetoMovible: public ObjetoEstatico {

protected:

	EstadoMovimiento estadoDerecha;
	EstadoMovimiento estadoIzquierda;
	EstadoMovimiento estadoSalto;

	int prioridad;
	int velocidad;
	int velocidadX;
	double velocidadY;
	int salto;
	Uint32 periodoSalto;
	Uint32 lastTimeSalto;
	int gravedad;
	int piso;
	bool activo;
	double realY;
	Punto posAnterior;
	
	Uint32 lastTimeActualizar;
	int estado;
	bool colisionandoX;
	bool colisionandoY;
	
	vector<Animacion*> v_acciones;
	vector<ObjetoMovible*> v_personajes;

public:

	ObjetoMovible(int x, int y, int maximoX, int maximoY, Orientacion orientacion = Derecha);
	virtual ~ObjetoMovible();
	
	//Setters atributos
	virtual void setEstado(int estado);
	void setActivo(bool activo);
	void setVelocidad(int vel);
	void setSalto(int salto);
	void setVelocidadY(double vel);
	void setVelocidadX(int vel);
	void setRealY(double y);
	void setPiso(int x);
	void setPeriodoSalto();
	void setGravedad(int gravedad);
	void setPosicion(int x, int y);
	void setLastTimeActualizar(Uint32 time);

	// Getters atributos
	int getEstado();
	int getActivo();
	int getEstadoSalto();
	int getSalto();
	Punto getPosicionAnt();
	int getVelocidad();
	int getVelocidadX();
	double getVelocidadY();
	double getRealY();
	int getPiso();
	int getGravedad();
	int getPrioridad();
	EstadoMovimiento* getDirEstadoDerecha();
	EstadoMovimiento* getDirEstadoIzquierda();
	EstadoMovimiento* getDirEstadoSalto();

	// Acciones
	virtual void MoverIzquierda(Uint32 deltaTime);
	virtual void MoverDerecha(int maximoX, Uint32 deltaTime);
	virtual void Saltar();
	void Frenar();
	virtual void caer(Uint32 deltaTime, int maximoY);
	vector<Animacion*> getAcciones();
	void addAccion(int idImagen, int cuadros);
	
	virtual void CambiarSentido(int posX, int anchoPlat, bool ownPos = false);
	virtual void Morir();
	
	virtual int indexEstado(int estado);
	virtual void Actualizar(Uint32 time);
	virtual pair<idImagen_t, int> getDibujable(Uint32 time);
	virtual pair<idImagen_t, int> getDibujable(Uint32 time, vector<ObjetoEstatico*> v_estaticos, vector<Obstaculo*> v_obstaculos, vector<ObjetoMovible*> v_movibles, ObjetoEstatico* princesa, vector<ObjetoMovible*> v_personajes);
	
	// Colisiones
	void detectarColisionesObstaculos(vector<Obstaculo*> v_obstaculos, vector<ObjetoEstatico*> v_estaticos);
	virtual void detectarColisionesMovibles(vector<ObjetoMovible*> v_movibles);
	int hayColisionX(int perIzq, int perDer, int obsIzq, int obsDer);
	int hayColisionY(int perSup, int perInf, int obsSup, int obsInf);

};

#endif /* MOVIBLE_H_ */
